﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kooboo.CMS.Content.Persistence;
using Kooboo.CMS.Sites.Persistence;
using Kooboo.CMS.Content.Models;
using Kooboo.CMS.Sites.Models;

namespace Kooboo.CMS.SchemaSyncWrapper
{
    public class SchemaProviderWrapper : ISchemaProvider
    {
        ISchemaProvider _schemaProvider;
        ISiteProvider _siteProvider;
        public SchemaProviderWrapper(ISchemaProvider schemaProvider, ISiteProvider siteProvider)
        {
            _schemaProvider = schemaProvider;
            _siteProvider = siteProvider;
        }
        private void DoSync(Site site, Repository originalRepository, Action<Repository> syncAction)
        {
            var siteRepository = site.GetRepository();
            if (siteRepository != originalRepository)
            {
                syncAction(siteRepository);
            }
            foreach (var sub in _siteProvider.ChildSites(site))
            {
                DoSync(sub, originalRepository, syncAction);
            }
        }
        public Content.Models.Schema Copy(Content.Models.Repository repository, string sourceName, string destName)
        {
            var schema = _schemaProvider.Copy(repository, sourceName, destName);

            DoSync(Site.Current, repository, delegate(Repository target)
            {
                _schemaProvider.Copy(target, sourceName, destName);
            });
            return schema;
        }

        public Content.Models.Schema Create(Content.Models.Repository repository, string schemaName, System.IO.Stream templateStream)
        {
            var schema = _schemaProvider.Create(repository, schemaName, templateStream);

            DoSync(Site.Current, repository, delegate(Repository target)
            {
                _schemaProvider.Create(target, schemaName, templateStream);
            });
            return schema;
        }

        public void Export(Content.Models.Repository repository, IEnumerable<Content.Models.Schema> models, System.IO.Stream outputStream)
        {
            _schemaProvider.Export(repository, models, outputStream);
        }

        public void Import(Content.Models.Repository repository, System.IO.Stream zipStream, bool @override)
        {
            _schemaProvider.Import(repository, zipStream, @override);

            DoSync(Site.Current, repository, delegate(Repository target)
            {
                _schemaProvider.Import(target, zipStream, @override);
            });

        }

        public void Initialize(Content.Models.Schema schema)
        {
            _schemaProvider.Initialize(schema);
        }

        public void Add(Content.Models.Schema item)
        {
            _schemaProvider.Add(item);
            var repository = item.Repository;
            DoSync(Site.Current, repository, delegate(Repository target)
            {
                item.Repository = target;
                _schemaProvider.Add(item);
            });
            item.Repository = repository;
        }

        public IQueryable<Content.Models.Schema> All(Content.Models.Repository repository)
        {
            return _schemaProvider.All(repository);
        }

        public Content.Models.Schema Get(Content.Models.Schema dummy)
        {
            return _schemaProvider.Get(dummy);
        }

        public void Remove(Content.Models.Schema item)
        {
            _schemaProvider.Remove(item);
            var repository = item.Repository;
            DoSync(Site.Current, repository, delegate(Repository target)
            {
                item.Repository = target;
                _schemaProvider.Remove(item);
            });
            item.Repository = repository;
        }

        public void Update(Content.Models.Schema @new, Content.Models.Schema old)
        {
            _schemaProvider.Update(@new, old);
            var repository = @new.Repository;
            DoSync(Site.Current, repository, delegate(Repository target)
            {
                @new.Repository = target;
                var itsOld = _schemaProvider.Get(@new);
                _schemaProvider.Update(@new, itsOld);
            });
            @new.Repository = repository;
        }
    }
}
